using FluentNHibernate.Mapping;
using NHibernateInsight.Tests.Domain;
using NHibernateInsight.Tests.Infrastructure;
using NUnit.Framework;

namespace NHibernateInsight.Tests.Insights.Relations.OneToMany
{
    /// <summary>
    /// Saving entities works both in and out of transaction (as opposite to many-to-many!)
    /// 
    /// Only one note about FluentNH...when mapping One side 
    /// of One-to-Many...use "References" instead of "HasOne"!
    /// </summary>
    [TestFixture]
    public class Saving_the_related_entites_when_many_side_is_a_bag : TestContext
    {
        private class Mappings_of
        {
            public class Prospect : ClassMap<Domain.Prospect>
            {
                public Prospect()
                {
                    Id(x => x.Id)
                        .GeneratedBy.Native();
                    Map(x => x.Initials);
                    HasMany(x => x.Orders)
                        .Cascade.SaveUpdate()
                        .Inverse()
                        .AsBag();
                }
            }
            public class Order : ClassMap<Domain.Order>
            {
                public Order()
                {
                    Id(x => x.Id)
                        .GeneratedBy.Native();
                    References(x => x.Prospect)
                        .Not.Nullable()
                        .Cascade.SaveUpdate();
                }
            }
        }

        [SetUp]
        public void Given_that()
        {
            PrepareForSql2005ExpressDb();

            HideCreateAndDropDbSqlFromConsole();
            HideCreateAndDropSchemaSqlFromConsole();
        }

        [TearDown]
        public void Cleanup_database()
        {
            Cleanup();
        }

        /// <summary>
        /// Then relation and entities will be saved
        /// </summary>
        [Test]
        public void When_saving_both_Entities_in_relation_without_transaction()
        {
            Init(m => m.FluentMappings
                          .Add<Mappings_of.Prospect>()
                          .Add<Mappings_of.Order>());

            var order1 = new Order();
            var order2 = new Order();
            var order3 = new Order();
            var order4 = new Order();
            var order5 = new Order();
            var prospect = new Prospect() { Initials = "Initials" };

            prospect.RelateTo(order1);
            prospect.RelateTo(order2);
            prospect.RelateTo(order3);
            prospect.RelateTo(order4);
            prospect.RelateTo(order5);

            CurrentSession.SaveOrUpdate(prospect);
        }

        /// <summary>
        /// Then relation and entities will be saved
        /// </summary>
        [Test]
        public void When_saving_both_Entities_in_relation_within_transaction()
        {
            Init(m => m.FluentMappings
                          .Add<Mappings_of.Prospect>()
                          .Add<Mappings_of.Order>());

            var order1 = new Order();
            var order2 = new Order();
            var order3 = new Order();
            var order4 = new Order();
            var order5 = new Order();
            var prospect = new Prospect() { Initials = "Initials" };

            prospect.RelateTo(order1);
            prospect.RelateTo(order2);
            prospect.RelateTo(order3);
            prospect.RelateTo(order4);
            prospect.RelateTo(order5);


            using (var tran = CurrentSession.BeginTransaction())
            {
                CurrentSession.SaveOrUpdate(prospect);

                tran.Commit();
            }
        }
    }
}